home *** CD-ROM | disk | FTP | other *** search
- ; File HFSOpen.TXT
- ;--------------------------------------------------------------------
- ;
- ; HFS Open Patch
- ;
- ; written by Andy Hertzfeld December 1985
- ;
- ; This program installs an init resource that patches the open
- ; and OpenRF calls in the file system to work harder at opening a file.
- ; It navigates the entire HFS catalog if a file isn't found,
- ; only returning "File Not Found" if the file isn't in any
- ; sub-directory. It should let MDS and other programs work
- ; more smoothly with HFS.
- ;
- ;--------------------------------------------------------------------
-
- INCLUDE MacTraps.D
-
- XDEF START
-
- ; I/O Equates
-
- IOCompletion EQU 12 ;offset to completion routine address
- IOResult EQU 16 ;offset to I/O result
- IOFileName EQU 18 ;offset to fileName
- IOVRefNum EQU 22 ;offset to volume refNum
- IORefNum EQU 24 ;offset to file refnum
-
- IOFileType EQU 26 ;offset to type byte, permissions
- IOMisc EQU 28 ;offset to misc param
- IOBuffer EQU 32 ;offset to buffer pointer
- IOByteCount EQU 36 ;offset to count
- IONumDone EQU 40 ;offset to number done
- IOPosMode EQU 44 ;offset to positioning mode
- IOPosOffset EQU 46 ;offset to position value
- IODirID EQU 48 ;offset to directory ID
-
- CSCode EQU 26 ;control code offset
- CSParam EQU 28 ;control parameter offset
-
- ; low memory equates
-
- KeyMap EQU $174 ;keyboard bitmap
- VCBQueue EQU $356 ;VCB Queue Header
- FCBSize EQU $3F6 ;new file system FCB size
- CurApRefNum EQU $900 ;our own refNum
-
-
- StartOfInit
- BRA InstallIt
-
-
-
-
-
- ; first run the normal system open routine and see what kind of errors
- ; we get.
-
- OpenPatch
- PEA BackFromOpen
- MOVE.L OldOpenAddr,-(SP) ;invoke real open routine
- RTS
-
- ; we ran it so check out the errors
-
- BackFromOpen
- BEQ.S DoneOpenPatch ;if no errors, we're file
- CMP.W #-43,D0 ;file not found?
- BNE.S NormalOpen ;if so, go to work
-
- ; it was "file not found" so try to search the catalog
-
- MOVEQ #0,D0 ;flag it's an open
- BSR SearchForFile
-
- ; it's some other error so there's nothing we can do about it
-
- NormalOpen
- TST.W D0 ;fix up condition codes
- DoneOpenPatch
- RTS
-
- ; OpenRF is handled the same as open
-
- OpenRFPatch
- PEA BackFromOpenRF
- MOVE.L OldOpenRFAddr,-(SP) ;invoke real open routine
- RTS
-
-
- ; we ran it so check out the errors
-
- BackFromOpenRF
- BEQ.S DoneOpenPatch ;if no errors, we're file
- CMP.W #-43,D0 ;file not found?
- BNE.S NormalOpen ;if so, go to work
-
- ; it was "file not found" so try to search the catalog
-
- MOVEQ #1,D0 ;flag it's an openRF
- BSR SearchForFile
- BRA.S NormalOpen
-
- ; GetFileInfo handler
-
- GFIPatch
- PEA BackFromGFI
- MOVE.L GFIAddr,-(SP) ;invoke real open routine
- RTS
-
- ; we ran it so check out the errors
-
- BackFromGFI
- BEQ.S DoneGFIPatch ;if no errors, we're file
- CMP.W #-43,D0 ;file not found?
- BNE.S NormalGFI ;if so, go to work
-
- ; if the name is NIL, give up
-
- TST.L IOFileName(A0)
- BEQ.S NormalGFI
-
- MOVE.B PatchOff,-(SP) ;disabled?
- TST.B (SP)+
- BNE.S NormalGFI ;if so, quit
-
- ; it was "file not found" so try to search the catalog
-
- MOVEQ #2,D0 ;flag it's a GetFileInfo
- BSR SearchForFile
-
- ; it's some other error so there's nothing we can do about it
-
- NormalGFI
- TST.W D0 ;fix up condition codes
-
- DoneGFIPatch
- RTS
-
- ; Delete handler
-
- DeletePatch
- PEA BackFromDelete
- MOVE.L DeleteAddr,-(SP) ;invoke real open routine
- RTS
-
- ; we ran it so check out the errors
-
- BackFromDelete
- BEQ.S DoneDeletePatch ;if no errors, we're file
- CMP.W #-43,D0 ;file not found?
- BNE.S NormalDelete ;if so, go to work
-
- ; it was "file not found" so try to search the catalog
-
- MOVEQ #3,D0 ;flag it's a Delete
- BSR SearchForFile
-
- ; it's some other error so there's nothing we can do about it
-
-
- NormalDelete
- TST.W D0 ;fix up condition codes
- DoneDeletePatch
- RTS
-
- ; SetFileInfo handler
-
- SFIPatch
- PEA BackFromSFI
- MOVE.L SFIAddr,-(SP) ;invoke real open routine
- RTS
-
- ; we ran it so check out the errors
-
- BackFromSFI
- BEQ.S DoneSFIPatch ;if no errors, we're file
- CMP.W #-43,D0 ;file not found?
- BNE.S NormalSFI ;if so, go to work
-
- ; if the name is NIL, give up
-
- TST.L IOFileName(A0)
- BEQ.S NormalSFI
-
- MOVE.B PatchOff,-(SP) ;disabled?
- TST.B (SP)+
- BNE.S NormalSFI ;if so, quit
-
- ; it was "file not found" so try to search the catalog
-
- MOVEQ #5,D0 ;flag it's a SetFileInfo
- BSR SearchForFile
-
- ; it's some other error so there's nothing we can do about it
-
- NormalSFI
- TST.W D0 ;fix up condition codes
-
- DoneSFIPatch
- RTS
-
- ; The CreatePatch is different from the others, since no search is
- ; involved. If there is exactly one colon in the name, parse it
- ; and do the create into the proper subdirectory. It's dangerous, so
- ; only do with option down
-
- CreatePatch
- BTST #2,KeyMap+7
- BEQ.S OldCreate
-
- TST.W FCBSize ;new file system?
- BPL.S HFSCreate ;if so, skip
- OldCreate
- MOVE.L CreateAddr,-(SP) ;handle normally
- RTS
-
- HFSCreate
- MOVEQ #4,D0 ;flags it's create
-
- ; SearchForFile examines the file name, parses it into a name/vRefNum
- ; specification, searches the HFS catalog for a matching filename,
- ; and re-runs the call if it finds on.
-
- SearchForFile
- LINK A6,#-258 ;allocate temp space
- MOVEM.L D2-D4/A0-A3,-(SP) ;save work registers
- MOVE.L D1,-(SP) ;keep D1 on top
-
- MOVE.W D0,-258(A6) ;remember Open/RF selector
- MOVE.L A0,A3 ;remember pBlock ptr
-
- TST.W FCBSize ;HFS installed?
- BMI SearchFailed ;if not, give up
-
- MOVE.L IOFileName(A3),A0 ;get name ptr
- MOVEQ #0,D0
- MOVE.B (A0)+,D0 ;get name size
-
- CMP.B #':',(A0) ;first character a colon?
- BEQ SearchFailed ;if so, we failed
-
- ; loop, searching for the colon
-
- ScanForColon
- CMP.B #':',(A0)+ ;got a colon?
- BEQ FoundColon
-
-
-
- SUBQ #1,D0 ;more to search?
- BGT.S ScanForColon ;if so, keep looking
-
- ; there wasn't a colon in the filename, so better no search, as it
- ; will really slow use down on those optional files. Option key
- ; down and we will...
-
- BTST #2,KeyMap+7
- BEQ SearchFailed
-
- MOVE.L IOFileName(A3),A0 ;point to source
- LEA -256(A6),A1 ;name buffer
- MOVEQ #0,D0
- MOVE.B (A0),D0
- ADDQ #1,D0
- _BlockMove ;move in the name
-
- MOVE.W IOVRefNum(A3),D3 ;get the VRefNum
-
- ; OK, now search the HFS catalog, looking for the filename at -256(A6)
- ; on the volume whose vRefNum is in D3. Also, handle create mode
- ; specially
-
-
- DoTheSearch
- CMP.W #4,-258(A6) ;create mode?
- BEQ.S DoCreate ;if so, handle specially
-
- LEA PatchOff,A0
- ST (A0) ;GFI patch off!
-
- MOVE.L LastDirID,D0 ;get last directory ID
- BEQ SearchFromRoot ;skip 1st search
-
- SUBQ #4,SP ;make room for result
- MOVE.W D3,-(SP) ;push the vRefNum
- MOVE.L D0,-(SP) ;start at the root
- PEA -256(A6) ;push file name
- BSR SearchCatalog
- MOVE.L (SP)+,D0 ;get the result
- BEQ SearchFromRoot ;if not found, we failed
-
- ; OK, we found the filename in a sub-directory, so open it as a
- ; working directory
-
- FoundIt
- LEA PatchOff,A0
- CLR.B (A0) ;back on again
-
- LEA LastDirID,A0 ;point to dirID variable
- MOVE.L D0,(A0) ;update variable
-
- SUB.W #80,SP
- MOVE.L SP,A0
- CLR.L IOFileName(A0)
- MOVE.W D3,IOVRefNum(A0) ;set up vRefNum
- MOVE.L #'PTCH',28(A0) ;set up proc ID
-
- MOVE.L D0,48(A0) ;set up dir ID
-
- MOVEQ #1,D0 ;OpenWD trap
- DC.W $A260 ;new file system call
-
- MOVE.W IOVRefNum(A0),D3 ;remember path refNum
- ADD.W #80,SP
-
- ; now retry the trap, using the new vRefNum/name
-
- MOVE.L (SP),D1 ;recover D1
-
-
-
- MOVE.L IOFileName(A3),-(SP) ;save old filename
- MOVE.W IOVRefNum(A3),-(SP) ;save old vRefNum
-
- LEA -256(A6),A1 ;get name pointer
- MOVE.L A1,IOFileName(A3) ;save as the filename
- MOVE.W D3,IOVRefNum(A3)
- MOVE.L A3,A0
-
- PEA DoneSearch1 ;push return address
-
- ; compute the trap address using the table
-
- MOVE.W -258(A6),D0 ;get switch value
- ASL.W #2,D0 ;multiply by 4
- MOVE.L OldOpenAddr(D0),-(SP) ;push address
- RTS ;go do it
-
- ; DoCreate does a special create using the parsed file name and
- ; lastDirID. Don't do it if we find 2 colons in the name, though
-
- DoCreate
- MOVE.L IOFileName(A3),A0 ;get name ptr
- MOVEQ #0,D0 ;clear length
- MOVEQ #0,D1 ;clear counter
- MOVE.B (A0)+,D0 ;get length
- CntColLoop
-
- CMP.B #':',(A0)+ ;a colon?
- BNE.S @0
-
- ADDQ #1,D1 ;count it
- @0
- SUBQ #1,D0
- BGT.S CntColLoop
-
- SUBQ #1,D1 ;exactly one colon?
- BNE SearchFailed ;if not, don't proceed
-
- ; do a special create call, using lastDirID
-
- MOVE.L LastDirID,D0
-
- BEQ SearchFailed ;make sure there is one
-
- SUB.W #80,SP
- MOVE.L SP,A0
-
- LEA -256(A6),A1
- MOVE.L A1,IOFileName(A0) ;use parsed name
- MOVE.W D3,IOVRefNum(A0) ;use vRefNum
- MOVE.L LastDirID,IODirID(A0)
- CLR.W IOFileType(A0)
- CLR.L IOMisc(A0)
-
- MOVE.W #$A208,D1 ;flag it's HCreate
-
- PEA BackFromCreate ;we're done
- MOVE.L CreateAddr,-(SP) ;push address
- RTS ;invoke it
-
- BackFromCreate
- ADD.W #80,SP ;pop off pBlock
- BRA DoneSearchFile ;all done
-
- ; addresses of the normal receivers for the five patched out routines
-
- OldOpenAddr
- DC.W 0,0
- OldOpenRFAddr
- DC.W 0,0
- GFIAddr
- DC.W 0,0
- DeleteAddr
- DC.W 0,0
- CreateAddr
- DC.W 0,0
- SFIAddr
- DC.W 0,0
- PatchOff
- DC.W 0
-
- ; all done, so return the result in D0
-
- DoneSearch1
- MOVE.W (SP)+,IOVRefNum(A3)
- MOVE.L (SP)+,IOFileName(A3)
- DoneSearchFile
- LEA PatchOff,A0
- CLR.B (A0)
-
- MOVE.L (SP)+,D1
- MOVEM.L (SP)+,D2-D4/A0-A3 ;restore registers
- UNLK A6 ;de-allocate locals
-
-
- TST.W D0
-
- RTS ;all done!
-
- ; handle the case where the search failed, returning "File not Found"
- ; special case create
-
- SearchFailed
- CMP.W #4,-258(A6) ;create mode?
- BEQ.S @0 ;if so, handle specially
-
- MOVEQ #-43,D0 ;return file not found
- BRA.S DoneSearchFile
- @0
- MOVE.L (SP)+,D1
- MOVEM.L (SP)+,D2-D4/A0-A3
- UNLK A6
- BRA OldCreate
-
- ; we couldn't find it starting from the last one, so search from the root
-
- SearchFromRoot
- MOVE.L LastDirID,D0 ;get last directory
-
- SUBQ.L #2,D0 ;was it the root?
- BEQ.S SearchFailed ;if so, don't do it twice
-
- SUBQ #4,SP ;make room for result
- MOVE.W D3,-(SP) ;push the vRefNum
- MOVE.L #2,-(SP) ;start at the root
- PEA -256(A6) ;push file name
- BSR SearchCatalog
- MOVE.L (SP)+,D0 ;get the result
- BNE FoundIt ;if we're lucky we found it
- BRA.S SearchFailed
-
- LastDirID
- DC.L 0 ;directory from last time
-
- ; FoundColon handles the case when the passed in name has a colon in it
- ; Use the part up to the colon to determine the vRefNum, and the part
- ; after the colon as the file name
-
- FoundColon
- LEA -256(A6),A1 ;destination
- SUBQ #1,D0 ;adjust size
- MOVE.B D0,(A1)+ ;length byte
- _BlockMove ;move in the rest
-
- ; now compute the length of the volume name in D1 and try to find
- ; it in the VCB queue
-
- MOVEQ #0,D0
- MOVE.L IOFileName(A3),A1 ;point to beginning of name
- SUB.L A1,A0 ;compute size
- MOVE.L A0,D1 ;get size
-
- ADDQ.L #1,A1 ;point at first char
- SUBQ.L #2,D1 ;adjust it
- BLE.S SearchFailed ;skip if bad spec
-
- ; now fly through the VCB queue, comparing against the name
-
- MOVE.L VCBQueue+2,D0 ;get first volume ptr
- BEQ.S SearchFailed
- VCBSearchLoop
- MOVE.L D0,A2
- LEA $2C(A2),A0 ;point to volName
-
- MOVEQ #0,D0
- MOVE.B (A0)+,D0 ;get length, point at 1st char
- SWAP D0
- MOVE.W D1,D0
- _CmpString ;compare with string in A1
- BEQ.S FoundTheVol
-
- MOVE.L (A2),D0
- BNE.S VCBSearchLoop
-
- BRA SearchFailed
-
- ; we found the volume. The name is already at -256(A6) so get the
- ; vRefNum in D3 and dive back in
-
- FoundTheVol
- MOVE.W 78(A2),D3 ;get the vRefNum
- BRA DoTheSearch
-
-
- ; FUNCTION SearchCatalog(vRefNum:INTEGER; curDir: LongInt; fName: Str255):LongInt
-
- ;
- ; SearchCatalog searches an HFS volume or sub-directory for a file with
- ; a given name It returns the directory ID of the directory
- ; holding the file, or 0 if it couldn't be found.
-
-
- SearchCatalog
- LINK A6,#-108 ;allocate pBlock
- CLR.L 18(A6) ;set result to 0
-
- ; better make sure we're running the new file system
-
- TST.W FCBSize ;for now, check new ROM
- BMI DoneSCatalog ;if not, we're done
-
- ; first do a file-name specific HGetFileInfo to see if the file is in
- ; the directory.
-
-
-
- LEA -108(A6),A0 ;point A0 at pBlock
- LEA 8(A6),A1 ;point at parameters
-
- MOVE.L (A1)+,IOFileName(A0) ;set up the name
- MOVE.L (A1)+,IODirID(A0) ;set up directory ID
- MOVE.W (A1)+,IOVRefNum(A0) ;set up vRefNum
- CLR.W IOMisc(A0) ;clear type and index
-
- MOVE.L 12(A6),D1 ;get this dirID in D1
- DC.W $A20C ;HGetFileInfo
- BEQ.S SCGotIt ;if found, skip
-
- ; it's not in the current directory, so index through all nodes to
- ; recursively explore the sub-directories
-
- CheckSubdirs
-
- CLR.L IOFileName(A0) ;don't want the name back
- MOVE.W #1,IOMisc(A0) ;start with the first one
- SCatLoop
- LEA -108(A6),A0 ;point to the pBlock
- MOVE.L 12(A6),IODirID(A0) ;re-establish directory ID
-
- MOVEQ #9,D0 ;HGetCatInfo call
- DC.W $A260 ;invoke HFS
- BNE.S DoneSCatalog ;on error, give up
-
- ; check if the current node is a directory
-
- BTST #4,30(A0) ;a directory?
- BNE.S CallSCAgain ;if so, go handle it
-
- ; keep looping until we've inspected them all
-
- NextSCatalog
- ADDQ.W #1,IOMisc(A0) ;bump the index
- BRA.S SCatLoop ;loop until error
-
- ; the current node is a directory, so call ourselves recursively to
- ; deal with it
-
- CallSCAgain
- SUBQ #4,SP ;make room for result
- MOVE.W 16(A6),-(SP) ;same vRefNum
-
- MOVE.L IODirID(A0),-(SP) ;new directory ID
- MOVE.L 8(A6),-(SP) ;same file name
- BSR SearchCatalog ;call ourselves
-
- LEA -108(A6),A0 ;re-establish A0
- MOVE.L (SP)+,D1 ;get directory ID
- BEQ.S NextSCatalog ;if none, skip
-
- ; we found it and D1 has the directory ID
-
- SCGotIt
- MOVE.L D1,18(A6) ;return the result
- DoneSCatalog
- UNLK A6
-
- MOVE.L (SP)+,A0
- ADD.W #10,SP ;strip parameters
- JMP (A0)
-
- ; InstallIt is the routine that installs the above in the system heap
-
-
- InstallIt
-
- MOVEM.L A2-A3,-(SP)
-
- LEA OldOpenAddr,A1 ;point to saved address table
- LEA PatchNumbers,A2 ;point to traps to patch
- LEA PatchAddresses,A3
-
- MOVE.W (A2)+,D2 ;get # to do
- InstallLoop
- MOVE.W (A2),D0
- _GetTrapAddress
-
- MOVE.L A0,(A1)+ ;save old address
-
- LEA StartOfInit,A0 ;get base address
- ADD.W (A3)+,A0 ;compute address
- MOVE.W (A2)+,D0 ;get trap number
- _SetTrapAddress
-
- DBRA D2,InstallLoop
-
- MOVEM.L (SP)+,A2-A3
- RTS
-
- PatchNumbers
- DC.W 5 ;6 patches to do
- DC.W 0,10,12,9,8,13
- PatchAddresses
- DC.W OpenPatch-StartOfInit
- DC.W OpenRFPatch-StartOfInit
- DC.W GFIPatch-StartOfInit
- DC.W DeletePatch-StartOfInit
- DC.W CreatePatch-StartOfInit
- DC.W SFIPatch-StartOfInit
- ;-------------------------------------------------------------------------
- ;
- ; Here is the code that isn't part of the INIT resource. It receives
- ; control when the application is run and installs the Init resource
- ; in the system resource file.
- ;
-
- ;--------------------------------------------------------------------------
-
- Start
-
- ; first allocate some zeroed space by clearing it off the stack
-
- MOVE #511,D0 ;need about 2K bytes
- ClearLoop
- CLR.L -(SP)
- DBRA D0,ClearLoop
-
- ; initialize QuickDraw and the toolBox
-
- InitWorld
- PEA -4(A5) ;push address of QuickDraw vars
- _InitGraf ;initialize QuickDraw
- _InitFonts ;initialize the font manager
- _InitCursor ;get the arrow cursor
- _InitWindows ;initialize the window manager
-
- _InitMenus ;ditto for menus
-
- CLR.L -(SP) ;our recovery proc is NIL
- _InitDialogs ;initialize dialogs
- _TEInit ;and text edit, too
-
- ; display the info box
-
- BSR DisplayInfoBox
-
- ; compute size of INIT resource to be added
-
- LEA StartOfInit,A2
- LEA Start,A0
- MOVE.L A0,D0
- SUB.L A2,D0 ;compute size
- MOVE.L D0,D1 ;remember size
-
- ; allocate a handle for the INIT resource
-
- DC.W $A522 ;allocate a sysHeap handle
- BNE NoInstall ;if error, punt
-
- MOVE.L A0,A3 ;remember it in A3
-
- ; move in the code
-
- MOVE.L A2,A0 ;souce is in A2
- MOVE.L (A3),A1 ;destination
- MOVE.L D1,D0 ;set up size
- _BlockMove ;move it in
-
- ; make sure it's not already installed
-
- CLR -(SP)
- _SetResLoad ;resource loading off
-
- SUBQ #4,SP
- MOVE.L InitRType,-(SP)
- PEA OpenPatchName
- _GetNamedResource
- MOVE.L (SP)+,D0
- BEQ FindInitID
-
- ; it's already there, so remove it
-
- MOVE.L D0,-(SP) ;push resource handle
-
- CLR.W -(SP)
- _UseResFile ;use system file
-
- _RmveResource ;remove it
-
- ; compute the ID to use for the INIT resource
-
- FindInitID
- MOVEQ #8,D3 ;start with ID = 8
-
- INITIDLoop
- SUBQ #4,SP
- MOVE.L InitRType,-(SP) ;push INIT
- MOVE D3,-(SP) ;push the ID
- _GetResource
-
- MOVE.L (SP)+,D0 ;got it?
- BEQ.S AddTheInit ;if not, use that ID
-
- ADDQ #1,D3
- CMP.W #32,D3
- BLT.S INITIDLoop
-
- ST -(SP)
- _SetResLoad
-
- MOVEQ #2,D0
- DoError
- MOVE D0,-(SP) ;remember entry code
-
- SUBQ #2,SP
- MOVE D0,-(SP)
-
- CLR.L -(SP)
-
- MOVE.W CurApRefNum,-(SP)
- _UseResFile
-
- _StopAlert
- ADDQ #2,SP
-
- SUBQ #1,(SP)+ ;code 1?
- BEQ.S Reboot
-
- _ExitToShell
- NoInstall
- MOVEQ #3,D0
- BRA.S DoError
-
- ; Simply reboot
-
- Reboot
- RESET
-
- ; OK, the ID to use is in D3, so we can add the resource
-
- AddTheInit
- ST -(SP)
- _SetResLoad
-
- CLR -(SP)
- _UseResFile ;use the system file
-
- MOVE.L A3,-(SP) ;push the handle
- MOVE.L InitRType,-(SP) ;push INIT
- MOVE.W D3,-(SP) ;push the ID
-
- PEA OpenPatchName ;push the name
- _AddResource
-
- SUBQ #2,SP
- _ResError
- TST.W (SP)+
- BNE.S NoInstall
-
- ; set the attributes
-
- MOVE.L A3,-(SP) ;push the resource
- MOVE #82,-(SP) ;sysHeap,locked, changed
- _SetResAttrs ;set default attributes
-
- ; write it out then update the resFile
-
- MOVE.L A3,-(SP)
- _WriteResource
-
- SUBQ #2,SP
- _ResError
- MOVE (SP)+,D0
- BNE NoInstall
-
- CLR.W -(SP)
- _UpdateResFile
-
- SUBQ #2,SP
- _ResError
- MOVE (SP)+,D0
- BNE NoInstall
-
-
-
- ; better flush all the volumes
-
- MOVE.L VCBQueue+2,D0
- SUB.W #80,SP
- MOVE.L SP,A0
- FlushLoop
- MOVE.L D0,A1
- CLR.L IOFileName(A0)
- MOVE.W 78(A1),IOVRefNum(A0)
- _FlushVol
-
- MOVE.L (A1),D0
- BNE.S FlushLoop
-
- ADD.W #80,SP
-
- SuccessExit
-
- MOVEQ #1,D0
- BRA DoError
-
- ReleaseIt
- BRA.S SuccessExit
-
-
- ; DisplayInfoBox puts up the initial dialog
-
- DisplayInfoBox
-
- SUBQ #4,SP ;make space for result
- MOVE #1,-(SP) ;dialog ID = 1
- CLR.L -(SP) ;allocate window in heap
-
- MOVEQ #-1,D0
- MOVE.L D0,-(SP) ;frontmost window
- _GetNewDialog ;make it the dialog
- WarnSTLoop
- CLR.L -(SP) ;no filterProc
- PEA -200(A5) ;place for result
- _ModalDialog ;let Bruce fetch events
-
- MOVE.W -200(A5),D0 ;get result
- SUBQ #1,D0
- BEQ.S WarnOK ;if 1, its OK
- SUBQ #1,D0 ;cancel?
- BNE.S WarnSTLoop ;if not, loop
-
- _DisposDialog
- ADDQ #4,SP
- _ExitToShell
-
- WarnOK
- _DisposDialog
- RTS
-
-
- ; strings, etc
-
- InitRType
- DC.B 'INIT'
- OpenPatchName
-
- DC.B 9,'OpenPatch'
-
-
-
-
-
-